package com.incross.dawin.views;


import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.MediaController.MediaPlayerControl;

import com.incross.dawin.util.BKLog;
import com.incross.dawin.util.CommonUtils;
import com.incross.dawin.util.CommonUtils.ScreenSize;


public class BKVideoPlayer extends SurfaceView implements MediaPlayerControl, SurfaceHolder.Callback,
	MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnVideoSizeChangedListener,
	MediaPlayer.OnErrorListener {


	// all possible internal states
	public static final int STATE_ERROR = -1;

	public static final int STATE_IDLE = 0;

	public static final int STATE_PREPARING = 1;

	public static final int STATE_PREPARED = 2;

	public static final int STATE_PLAYING = 3;

	public static final int STATE_PAUSED = 4;

	private static final int STATE_PLAYBACK_COMPLETED = 5;

	private static final int STATE_SUSPEND = 6;

	private static final int STATE_RESUME = 7;

	private static final int STATE_SUSPEND_UNSUPPORTED = 8;

	private static final int START_TAG_TIMER = 9876;

	private static final int TIMER_DELAY = 100;
	
	private static final int MESSAGE_VIDEO_START = 10000;
	
	private static final int MESSAGE_ADJUST_VIDEO = 104;

	private int mCurrentState = STATE_IDLE;

	private int mTargetState = STATE_IDLE;

	private Context mContext;

	private int mDuration = -1;

	private int mCurrentBufferPercentage;

	private String mUri;

	private MediaPlayer mMediaPlayer;
	
	private boolean mIsVideoPrepared = false;

	private SurfaceHolder mSurfaceHolder;

	private int mSurfaceWidth, mSurfaceHeight;

	private int mVideoWidth = 0, mVideoHeight = 0;

	private int mWidthMeasureSpec, mHeightMeasureSpec;

	private int mWidthRatio = -1, mHeightRatio = -1;

	// parent view informations
	private int mPortParentWidth = 0, mPortParentHeight = 0;

	private int mLandParentWidth = 0, mLandParentHeight = 0;

	private boolean mIsPortParentAvailable = false, mIsLandParentAvailable = false;

	private boolean mIsMediaPlayerPrepared = false;

	private boolean mIsStartTimerRunning = false;

	private int mStartPosition = 0;
	
	private boolean mIsVideoPlayerReleased = false;
	

	// callback listeners
	private OnPlayFinishListener mPlayFinishListener;

	private OnPreparedListener mPreparedListener;

	private OnVideoErrorListener mVideoErrorListener;

	private OnVideoStartListener mVideoStartListener;
	
	private int mPortFixedWidth = 0, mPortFixedHeight = 0;
	private int mLandFixedWidth = 0, mLandFixedHeight = 0;
	
	private Timer mStartTimer;
	private TimerTask mStartTimerTask;

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch(msg.what) {
				case MESSAGE_VIDEO_START:
					if(mVideoStartListener != null) {
						mVideoStartListener.onVideoStarted();
					}
					break;
				// 20141112 기획팀과 협의하에 비디오 비율 무시하고 무조건 영상영역에 채우도록 변경함	
				/*case MESSAGE_ADJUST_VIDEO:
					changeDimension();
					break;*/
			}
		}
	};


	private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {

		public void onBufferingUpdate(MediaPlayer mp, int percent) {
			mCurrentBufferPercentage = percent;
		}
	};


	public interface OnPlayFinishListener {

		public abstract void onPlayFinished(MediaPlayer mp);
	}

	public interface OnPreparedListener {

		public abstract void onPrepared(MediaPlayer mp);
	}

	public interface OnVideoErrorListener {

		public abstract void onVideoError(MediaPlayer mp, int errorCode);
	}

	public interface OnVideoStartListener {

		public abstract void onVideoStarted();
	}


	// public constructors
	public BKVideoPlayer(Context context) {
		super(context);
		mContext = context;
		initVideoView();
	}

	public BKVideoPlayer(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
		mContext = context;
		initVideoView();
	}

	public BKVideoPlayer(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		mContext = context;
		initVideoView();
	}

	private void initVideoView() {
		mVideoWidth = 0;
		mVideoHeight = 0;
		mSurfaceHolder = getHolder();

		getHolder().addCallback(this);
		getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		getHolder().lockCanvas();
		setFocusable(true);
		setFocusableInTouchMode(true);
		requestFocus();
		mCurrentState = STATE_IDLE;
		mTargetState = STATE_IDLE;
		
		initStartTimer();
	}
	
	private void initStartTimer() {
		if(mStartTimer == null) {
			mStartTimer = new Timer();
		} else {
			mStartTimer.cancel();
			mStartTimer.purge();
			if(mStartTimerTask != null) {
				mStartTimerTask.cancel();
			}
		}
		
		if(mStartTimerTask == null) {
			mStartTimerTask = new TimerTask() {
				@Override
				public void run() {
					BKLog.d("Start Timer ----");
					if(getCurrentPosition() > mStartPosition) {
						mHandler.sendEmptyMessage(MESSAGE_VIDEO_START);
						cancelTimer();
					}
				}
			};
		}
	}
	
	
	private boolean startTimer() {
		try {
			if(!mIsStartTimerRunning && mStartTimer != null && mStartTimerTask != null) {
				mIsStartTimerRunning = true;
				mStartTimer.schedule(mStartTimerTask, 0, 100);
			}
			return true;
		} catch(IllegalStateException e) {
			e.printStackTrace();
			return false;
		}
	}
	
	private void cancelTimer() {
		if(mIsStartTimerRunning) {
			mIsStartTimerRunning = false;
			mStartTimer.cancel();
			mStartTimer.purge();
			mStartTimer = null;
			
			mStartTimerTask.cancel();
			mStartTimerTask = null;
		}
	}

	public void setVideoURI(String uri) {
		mUri = uri;
		openVideo();
//		requestLayout();
		invalidate();
	}


	/*public void prepareVideo(String videoPath) {
		if(mMediaPlayer != null) {
			try {
				mMediaPlayer.setDataSource(videoPath);
				mMediaPlayer.prepare();
			} catch(IllegalArgumentException e) {
				e.printStackTrace();
			} catch(IllegalStateException e) {
				e.printStackTrace();
			} catch(IOException e) {
				e.printStackTrace();
			}
		} else {
			if(mVideoErrorListener != null) {
				mVideoErrorListener.onVideoError(mMediaPlayer, 0);
			}
		}
	}*/


	private void openVideo() {
		BKLog.w("OpenVideo");
		if(mUri == null || mSurfaceHolder == null) {
			// not ready for playback just yet, will try again later
			return;
		}
		// Tell the music playback service to pause
		Intent i = new Intent("com.android.music.musicservicecommand");
		i.putExtra("command", "pause");
		mContext.sendBroadcast(i);
		// we shouldn't clear the target state, because somebody might have
		// called start() previously
		try {
			if(mMediaPlayer == null) {
				mMediaPlayer = new MediaPlayer();
			}
			mMediaPlayer.setOnPreparedListener(this);
			mMediaPlayer.setOnVideoSizeChangedListener(this);
			mDuration = -1;
			mMediaPlayer.setOnCompletionListener(this);
			mMediaPlayer.setOnErrorListener(this);
			mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
			mCurrentBufferPercentage = 0;
			mMediaPlayer.setDataSource(mUri);
			mMediaPlayer.setDisplay(mSurfaceHolder);
			mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
			mMediaPlayer.setScreenOnWhilePlaying(true);
			mMediaPlayer.prepareAsync();
			// we don't set the target state here either, but preserve the
			// target state that was there before.
			mCurrentState = STATE_PREPARING;
		} catch(IOException ex) {
			mCurrentState = STATE_ERROR;
			if(mVideoErrorListener != null) {
				mVideoErrorListener.onVideoError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN);
			}
			return;
		} catch(IllegalArgumentException ex) {
			mCurrentState = STATE_ERROR;
			if(mVideoErrorListener != null) {
				mVideoErrorListener.onVideoError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN);
			}
			return;
		} catch(IllegalStateException e) {
			mCurrentState = STATE_ERROR;
			if(mCurrentState != STATE_IDLE) {
				if(mVideoErrorListener != null) {
					BKLog.e("Video not initialized");
					mVideoErrorListener.onVideoError(mMediaPlayer, DawinAdPlayer.DAWIN_ERROR_PLAYER_NOT_INITIALIZED);
				}
			} else {
				if(mVideoErrorListener != null) {
					mVideoErrorListener.onVideoError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN);
				}
			}
		}
	}

	public void release() {
		if(mMediaPlayer != null) {
			BKLog.w("======== Release =========");
			if(isPlaying()) {
				try {
					mMediaPlayer.pause();
					mMediaPlayer.stop();
					mMediaPlayer.reset();
					mMediaPlayer.release();
				} catch(IllegalStateException e) {
					e.printStackTrace();
				} catch(Exception e) {
					e.printStackTrace();
				}
			}
			
			mMediaPlayer = null;
			mCurrentState = STATE_IDLE;
			mIsVideoPrepared = false;
			cancelTimer();
			BKLog.w("======== Release =========");
		}
		mIsVideoPlayerReleased = true;
	}
	
	public void reset() {
		if(mMediaPlayer != null) {
			try {
				if(isPlaying()) {
					mMediaPlayer.pause();
					mMediaPlayer.stop();
				}
				mMediaPlayer.reset();
			} catch(Exception e) {
				e.printStackTrace();
				if(mVideoErrorListener != null) {
					mVideoErrorListener.onVideoError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN);
				}
			} finally {
				mCurrentState = STATE_IDLE;
				initStartTimer();
				resetVariables();
			}
		}
	}
	
	private void resetVariables() {
		mCurrentState = STATE_IDLE;
		mTargetState = STATE_IDLE;
		
		mIsVideoPrepared = false;
		
//		mIsPortParentAvailable = false;
//		mIsLandParentAvailable = false;
//		
//		mPortParentWidth = 0;
//		mPortParentHeight = 0;
//		mLandParentWidth = 0;
//		mLandParentHeight = 0;
	}
	
	// 20141112 기획팀과 협의하에 비디오 비율 무시하고 무조건 영상영역에 채우도록 변경함
	/*public void setParentViewSize(int orientation, int width, int height) {
		switch(orientation) {
			case Configuration.ORIENTATION_PORTRAIT:
				if(!mIsPortParentAvailable) {
					BKLog.i("BKVideoView - Portrait parent size set complete(width : " + width + ", height : " + height + ")");
					mIsPortParentAvailable = true;
					mPortParentWidth = width;
					mPortParentHeight = height;
					setFixedVideoSize(Configuration.ORIENTATION_PORTRAIT);
					mHandler.sendEmptyMessage(MESSAGE_ADJUST_VIDEO);
				}
				break;
				
				
			case Configuration.ORIENTATION_LANDSCAPE:
				if(!mIsLandParentAvailable) {
					BKLog.i("BKVideoView - Landscape parent size set complete(width : " + width + ", height : " + height + ")");
					mIsLandParentAvailable = true;
					mLandParentWidth = width;
					mLandParentHeight = height;
					setFixedVideoSize(Configuration.ORIENTATION_LANDSCAPE);
					mHandler.sendEmptyMessage(MESSAGE_ADJUST_VIDEO);
				}
				
				break;
		}
		
	}*/
	
	public boolean isParentSizeAvailable(int orientation) {
		boolean result = false;
		switch(orientation) {
			case Configuration.ORIENTATION_PORTRAIT:
				result = mIsPortParentAvailable;
				break;
				
			case Configuration.ORIENTATION_LANDSCAPE:
				result = mIsLandParentAvailable;
				break;
		}
		
		return result;
	}

	/*@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
		int width = displayMetrics.widthPixels;
		int height = displayMetrics.heightPixels;

		int rightMargin = width - r;
		int topMargin = t;
		int bottomMargin = height - b;
		int leftMargin = l;

		int currWidth = width - rightMargin - leftMargin;
		int currHeight = height - topMargin - bottomMargin;
		
		
		
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
			setParentViewSize(Configuration.ORIENTATION_PORTRAIT, currWidth, currHeight);
			changeDimension();
		} else {
			setParentViewSize(Configuration.ORIENTATION_LANDSCAPE, currWidth, currHeight);
			changeDimension();
		}
	}*/

	@Override
	public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		BKLog.d("onMeasure - Change do nothing");
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		// 20141112 기획팀과 협의하에 비디오 비율 무시하고 무조건 영상영역에 채우도록 변경함
		/*mWidthMeasureSpec = widthMeasureSpec;
		mHeightMeasureSpec = heightMeasureSpec;
		
		int parentWidth = 0, parentHeight = 0;
		
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
			parentWidth = mPortParentWidth;
			parentHeight = mPortParentHeight;
		} else {
			parentWidth = mLandParentWidth;
			parentHeight = mLandParentHeight;
		}

		if(parentWidth == 0 || parentHeight == 0) {
			if(mWidthRatio == -1 || mHeightRatio == -1) {
				super.onMeasure(widthMeasureSpec, heightMeasureSpec);
			} else {
				ScreenSize size = CommonUtils.getScreenSize(mContext);
				int width, height;
				if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
					width = size.getWidth();
					height = width / mWidthRatio * mHeightRatio;
				} else {
					height = size.getHeight();
					width = height / mHeightRatio * mWidthRatio;
				}
				setMeasuredDimension(width, height);
			}
		} else {
			if(mWidthRatio == -1 || mHeightRatio == -1) {
				super.onMeasure(widthMeasureSpec, heightMeasureSpec);
			} else {
				changeDimension();
			}
		}*/

	}
	
	// 20141112 기획팀과 협의하에 비디오 비율 무시하고 무조건 영상영역에 채우도록 변경함 - 주석처리
	/*public void changeDimension() {
		// must call after check parent view's size and video ratio set
		// call default measure if height ratio is bigger than width ratio.

		int width = mWidthMeasureSpec, height = mHeightMeasureSpec;
		int parentWidth, parentHeight;
		
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
			parentWidth = mPortParentWidth;
			parentHeight = mPortParentHeight;
		} else {
			ScreenSize size = CommonUtils.getScreenSize(mContext);
			parentWidth = size.getWidth();
			parentHeight = size.getHeight();
		}
		
		if(parentWidth > parentHeight) { // landscape
			BKLog.e("land, pw : " + parentWidth + ", ph : " + parentHeight);
			height = parentHeight;
			width = Math.round((float)parentHeight / (float)mHeightRatio * (float)mWidthRatio);
			
			if(width > parentWidth) {
				
				width = parentWidth;
				height = Math.round((float)parentWidth / (float) mWidthRatio * (float)mHeightRatio);
			}
			

		} else {
			BKLog.e("port, pw : " + parentWidth + ", ph : " + parentHeight);
			
			try {
				width = parentWidth;
				height = parentWidth / mWidthRatio * mHeightRatio;
			} catch(Exception e) {
				Log.w(getClass().getName(), "Exception occured. set default size");
				width = mVideoWidth;
				height = mVideoHeight;
			}
		}
		
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_LANDSCAPE) {
			if(mLandFixedWidth != 0 && mLandFixedHeight != 0) {
				width = mLandFixedWidth;
				height = mLandFixedHeight;
			}
		} else {
			if(mPortFixedWidth != 0 && mPortFixedHeight != 0) {
				width = mPortFixedWidth;
				height = mPortFixedHeight;
			}
		}
		
		setMeasuredDimension(width, height);
		mSurfaceHolder.setFixedSize(width, height);

		refreshDrawableState();
		BKLog.i("ChangeDimension()");
		BKLog.i("---------> measured width : " + width + ", measured Height : " + height);
		
	}*/


	public void setOnPreparedListener(OnPreparedListener l) {
		mPreparedListener = l;
	}

	public void setOnPlayFinishListener(OnPlayFinishListener l) {
		mPlayFinishListener = l;

	}

	public void setOnVideoErrorListener(OnVideoErrorListener l) {
		mVideoErrorListener = l;
	}

	public void setOnVideoStartListener(OnVideoStartListener l) {
		mVideoStartListener = l;
	}


	private boolean isInPlaybackState() {
		return (mMediaPlayer != null && mCurrentState != STATE_ERROR && mCurrentState != STATE_IDLE && mCurrentState != STATE_PREPARING);
	}
	
	public int getCurrentState() {
		return mCurrentState;
	}


	// MediaPlayerControl~

	@Override
	public boolean canPause() {
		if(mMediaPlayer != null && isPlaying()) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public boolean canSeekBackward() {
		return false;
	}

	@Override
	public boolean canSeekForward() {
		return false;
	}

	@Override
	public int getBufferPercentage() {
		return mCurrentBufferPercentage;
	}

	@Override
	public int getCurrentPosition() {
		int position = -1;
		try {
			position = mMediaPlayer.getCurrentPosition();
		} catch(Exception e) {
			return -1;
		}
		
		return position;
	}

	@Override
	public int getDuration() {
		try {
			if(mMediaPlayer != null) {
				mDuration = mMediaPlayer.getDuration();
			}
		} catch(Exception e) {
			return -1;
		}
		
		return mDuration;
	}

	@Override
	public boolean isPlaying() {
		try {
			if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
				return true;
			} else {
				return false;
			}
		} catch (IllegalStateException e) {
			// release 된 경우나 아직 prepared안된경우임
			return false;
		}
	}

	@Override
	public void pause() {
		if(mMediaPlayer != null && isPlaying()) {
			mMediaPlayer.pause();
			mCurrentState = STATE_PAUSED;
		}
		mTargetState = STATE_PAUSED;
	}

	@Override
	public void seekTo(int pos) {
		if(mMediaPlayer != null) {
			mMediaPlayer.seekTo(pos);
		}
	}

	@Override
	public void start() {
		if(isInPlaybackState()) {
			mMediaPlayer.start();
			mCurrentState = STATE_PLAYING;
		}
		mTargetState = STATE_PLAYING;
	}
	
	public void stop() {
		if(mMediaPlayer != null) {
			mMediaPlayer.stop();
		}
	}

	// SurfaceView callback methods

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//		mSurfaceWidth = width;
//		mSurfaceHeight = height;
//		BKLog.d("surface width : " + width + ", height : " + height);
//		boolean isValidState = (mTargetState == STATE_PLAYING);
//		boolean hasValidSize = (mVideoWidth == width && mVideoHeight == height);
//		if(mMediaPlayer != null && isValidState && hasValidSize) {
//			start();
//		}
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		try {
			if(mMediaPlayer == null) {
				mMediaPlayer = new MediaPlayer();
			} else {
				mMediaPlayer.reset();
			}
			mMediaPlayer.setDisplay(holder);
			mMediaPlayer.setOnPreparedListener(this);
		} catch(Exception e) {
			if(mVideoErrorListener != null) {
				mVideoErrorListener.onVideoError(mMediaPlayer, STATE_ERROR);
			}
		}
		
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
	}

	// MediaPlayer prepared
	@Override
	public void onPrepared(MediaPlayer mp) {
		BKLog.d("=============== onPrepared");
		if(!mIsVideoPlayerReleased) {
			mIsVideoPrepared = true;
			mCurrentState = STATE_PREPARED;
			setVideoSize(mp.getVideoWidth(), mp.getVideoHeight());
			mHandler.sendEmptyMessage(MESSAGE_ADJUST_VIDEO);
//			changeDimension();

			mIsMediaPlayerPrepared = true;
			BKLog.d("Video width : " + mVideoWidth + ", videoHeight : " + mVideoHeight);

			if(mPreparedListener != null) {
				mPreparedListener.onPrepared(mMediaPlayer);
			}
			if(!startTimer()) mHandler.sendEmptyMessage(MESSAGE_VIDEO_START);
		} else {
			if(mp != null) {
				mp.release();
			}
		}
		
	}

	private void setVideoSize(int width, int height) {
		mVideoWidth = width;
		mVideoHeight = height;
		
		BKLog.i("VideoWidth : " + width + ", height : " + height);

		int max = CommonUtils.getGreatestCommonMeasure(width, height);

		mWidthRatio = width / max;
		mHeightRatio = height / max;
		BKLog.i(mWidthRatio + ":" + mHeightRatio + " source.");
	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		if(mPlayFinishListener != null) {
			mPlayFinishListener.onPlayFinished(mMediaPlayer);
		}
		
		cancelTimer();
	}

	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		// 20140418 미디어 플레이어의 -38, 0은 오류상황 아닌 것으로 처리..
		BKLog.e("MediaPlayer error(what : " + what + ", extra : " + extra + ")");
		if(what == -38 && extra == 0) {
			// 오류아님!
			Log.w("BKVideoPlayer", "Skip error (" + what + ", " + extra +")");
		} else {
			if(mVideoErrorListener != null) {
				mVideoErrorListener.onVideoError(mMediaPlayer, what);
			}
		}
		return false;
	}

	@Override
	public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
		// TODO Auto-generated method stub
	}
	
	
	///////////////////////////////////////////////////////////////////////////
	
	private void setFixedVideoSize(int orientation) {
		// TODO : 영상 비율을 가져온 후 호출해야함.
		if(mWidthRatio != 0 && mHeightRatio != 0) {
			if(orientation == Configuration.ORIENTATION_LANDSCAPE) {
				if(mLandFixedWidth == 0 || mLandFixedHeight == 0) {
					ScreenSize size = getOptimalVideoSize(mLandParentWidth, mLandParentHeight, mWidthRatio, mHeightRatio);
					mLandFixedWidth = size.getWidth();
					mLandFixedHeight = size.getHeight();
					BKLog.i("##########################################################################");
					BKLog.i("LandFixed size set!!(w" + mLandFixedWidth + ",h" + mLandFixedHeight + ")");
					BKLog.i("##########################################################################");
				}
			} else {
				if(mPortFixedWidth == 0 || mPortFixedHeight == 0) {
					ScreenSize size = getOptimalVideoSize(mPortParentWidth, mPortParentHeight, mWidthRatio, mHeightRatio);
					mPortFixedWidth = size.getWidth();
					mPortFixedHeight = size.getHeight();
					BKLog.i("##########################################################################");
					BKLog.i("PortFixed size set!!(w" + mPortFixedWidth + ",h" + mPortFixedHeight + ")");
					BKLog.i("##########################################################################");
				}
			}
		}
		
	}
	
	private ScreenSize getOptimalVideoSize(int width, int height, int widthRatio, int heightRatio) {
		
		
		ScreenSize size = null;
		if(widthRatio == -1 || heightRatio == -1) {
			// default size
			widthRatio = 16;
			heightRatio = 9;
		}
		
		int resultWidth = 0;
		int resultHeight = 0;
		
		resultWidth = width;
		resultHeight = (width / widthRatio) * heightRatio;
		
		if(resultWidth > width || resultHeight > height) {
			resultWidth = (height / heightRatio) * widthRatio;
			resultHeight = height;
		}
		
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_LANDSCAPE) {
			if(mLandFixedWidth == 0 || mLandFixedHeight == 0) {
				mLandFixedWidth = resultWidth;
				mLandFixedHeight = resultHeight;
			} else {
				resultWidth = mLandFixedWidth;
				resultHeight = mLandFixedHeight;
			}
		} else {
			if(mPortFixedWidth == 0 || mPortFixedHeight == 0) {
				mPortFixedWidth = resultWidth;
				mPortFixedHeight = resultHeight;
			} else {
				resultWidth = mPortFixedWidth;
				resultHeight = mPortFixedHeight;
			}
		}
		
		size = new ScreenSize(resultWidth, resultHeight);
		
		return size;
	}

}
